﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using SyndicateDAO.DAO;
using SyndicateDAO.DatabaseObject;
using System.Web.SessionState;
using System.Web;

namespace SyndicateBusiness.Classes
{
    public class UserBL
    {
        private UserDAO UserDAO = new UserDAO();
        
        #region

        internal static HttpSessionState Session
        {
            get
            {
                if (HttpContext.Current == null)
                    return null;

                return HttpContext.Current.Session;
            }
        }

        internal static System.Collections.IDictionary Items
        {
            get
            {
                if (HttpContext.Current == null)
                    return null;

                return HttpContext.Current.Items;
            }
        }

        public int? LoggedInUserId
        {
            get
            {
                if (Session != null)
                {
                    if (Session["BigLotterySyndicate.LoggedInUserId"] == null && HttpContext.Current != null && HttpContext.Current.Request != null && HttpContext.Current.Request.Cookies["BigLotterySyndicateLoggedInUserId"] != null)
                        Session["BigLotterySyndicate.LoggedInUserId"] = Utilities.StringToInt(HttpContext.Current.Request.Cookies["BigLotterySyndicateLoggedInUserId"].Value);

                    if (Session["BigLotterySyndicate.LoggedInUserId"] != null)
                        return Int32.Parse(Session["BigLotterySyndicate.LoggedInUserId"].ToString());
                    else
                        return null;
                }
                else
                {
                    return null;
                }
            }
            set
            {
                if (Session == null)
                    return;

                if (value != null)
                    Session["BigLotterySyndicate.LoggedInUserId"] = value;
                else
                    Session.Remove("BigLotterySyndicate.LoggedInUserId");

                if (Items != null)
                    Items.Remove("BigLotterySyndicate.LoggedInUser");
            }
        }

        public user LoggedInUser
        {
            get
            {
                try
                {
                    if (Items != null && Items["BigLotterySyndicate.LoggedInUser"] == null && LoggedInUserId != null)
                        Items["BigLotterySyndicate.LoggedInUser"] = this.UserDAO.SelectSingle(LoggedInUserId.Value);
                    return (user)Items["BigLotterySyndicate.LoggedInUser"];
                }
                catch (System.Exception e)
                {
                    SyndicateDAO.Classes.Diagnostic.WriteToEventLog(e, e.Message);

                    return null;
                }
            }
            internal set
            {
                if (Items == null)
                    return;

                if (value != null)
                    Items["BigLotterySyndicate.LoggedInUser"] = value;
                else
                    Items.Remove("BigLotterySyndicate.LoggedInUser");

                if (Session != null)
                {
                    if (value != null)
                        Session["BigLotterySyndicate.LoggedInUserId"] = value.id;
                    else
                        Session.Remove("BigLotterySyndicate.LoggedInUserId");
                }
            }
        }

        public bool IsLoggedIn
        {
            get
            {
                return (LoggedInUserId != null);
            }
        }

        public bool IsAdmin(int userId)
        {
            user u = UserDAO.SelectSingle(userId);
            return u.isAdmin;
        }

        public void Logout(int userId)
        {
            Logout(userId, true);
        }

        public void Logout(int userId, bool removePersistentLogin)
        {
            user user = this.UserDAO.SelectSingle(userId);

            if (user == null)
                return;

            if (removePersistentLogin)
                PersistLoginRemove(userId);

            LoggedInUserId = null;
        }

        public void PersistLoginRemove(int userId)
        {
            PersistLogin(null, userId);
        }

        public bool Login(int userId)
        {

            user user = this.UserDAO.SelectSingle(userId);

            if (user == null)
                return false;

            Login(user, (TimeSpan?)null);

            return true;
        }

        public bool Login(string email,int syndicateId)
        {
            user user = this.UserDAO.SelectSingleByEmailForCurrentSyndicate(email, syndicateId);

            if (user == null)
                return false;

            Login(user, (TimeSpan?)null);

            return true;
        }

        public bool Login(string email, string password, int syndicateId, TimeSpan? timePersists)
        {
            String plainPassword = password;
            String encodedPassword = Utilities.EncodePassword(plainPassword);

            //test if user has plain password

            user user = this.UserDAO.SelectByEmailAndPasswordForCurrentSyndicate(email, encodedPassword, syndicateId);

            if (user == null)
                return false;

            Login(user, timePersists);

            return true;
        }

        public void Login(user user, TimeSpan? timePersists)
        {
           // User.loginCount = User.loginCount + 1;
            //this.UserDAO.Update();
            LoggedInUser = user;

            PersistLogin(timePersists, user.id);
        }

        public void PersistLogin(TimeSpan? time, int userId)
        {

            if (HttpContext.Current != null)
                PersistLogin(HttpContext.Current.Response, time, userId);
        }

        public static void PersistLogin(HttpResponse httpResponse, TimeSpan? time, int userId)
        {
            HttpCookie cookie = new HttpCookie("BigLotterySyndicateLoggedInUserId");

            if (time != null)
            {
                cookie.Value = userId.ToString(CultureInfo.InvariantCulture);
                cookie.Expires = DateTime.Now.Add(time ?? default(TimeSpan));
            }
            else
            {
                cookie.Value = String.Empty;
                cookie.Expires = DateTime.Now.AddDays(-1);
            }

            httpResponse.Cookies.Add(cookie);
        }

        public bool ValidateAccount(string emailValue, bool requireAdminRights,int syndicateId)
        {

            user user = this.UserDAO.SelectSingleByEmailForCurrentSyndicate(emailValue, syndicateId);

            if (user != null)
            {
                if (requireAdminRights)
                {
                    return (user.isAdmin);
                }
                else
                    return true;
            }
            else
            {
                return false;
            }
        }

        public bool ValidateAccountCheckActive(string emailValue, bool requireAdminRights, int syndicateId)
        {

            user user = this.UserDAO.SelectSingleByEmailForCurrentSyndicate(emailValue, syndicateId);

            if (user != null && user.isActive)
            {
                if (requireAdminRights)
                {
                    return (user.isAdmin);
                }
                else
                    return true;
            }
            else
            {
                return false;
            }
        }

        public bool ValidateAccountDB(string emailValue,string passValue,int syndicateId, bool requireAdminRights)
        {
            
            user user = this.UserDAO.SelectByEmailAndPasswordForCurrentSyndicate(emailValue,passValue,syndicateId);

            if (user != null)
            {
                if (requireAdminRights)
                {
                    return (user.isAdmin);
                }
                else
                    return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region DAO

        public IQueryable<user> GetAll(int sId)
        {
            return UserDAO.SelectAllBySyndicateId(sId);
        }

        public IQueryable<user> GetAll()
        {
            return UserDAO.SelectAll();
        }


        public IQueryable<user> GetAllBySyndicateId(int sId)
        {
            return UserDAO.SelectAllBySyndicateId(sId);
        }

        public IQueryable<user> GetAllBySyndicateId(DataContext dc,int sId)
        {
            return UserDAO.SelectAllBySyndicateId(dc,sId);
        }

        public user GetSingleUser(int uId)
        {
            return UserDAO.SelectSingleUser(uId);
        }

        public user GetSingleUserByToken(string token,int syndicateId)
        {
            return UserDAO.SelectAllBySyndicateId(syndicateId).SingleOrDefault(u => u.xmlToken == token);
        }
               
        public bool InsertUser(user d)
        {
            return UserDAO.Insert(d);
        }
        public bool UpdateUser()
        {
            return UserDAO.Update();
        }
        public bool DeleteUser(user d)
        {
            return UserDAO.Delete(d);
        }

        #endregion
    }
}
